package com.agileboot.admin.controller.performance;

import com.agileboot.common.core.dto.ResponseDTO;
import com.agileboot.common.core.page.PageDTO;
import com.agileboot.common.exception.ApiException;
import com.agileboot.common.exception.error.ErrorCode;
import com.agileboot.common.utils.poi.CustomExcelUtil;
import com.agileboot.domain.performance.score.UserScoreRecordApplicationService;
import com.agileboot.domain.performance.score.command.AddUserScoreRecordCommand;
import com.agileboot.domain.performance.score.command.UpdateUserScoreRecordCommand;
import com.agileboot.domain.performance.score.dto.RateLimitInfoDTO;
import com.agileboot.domain.performance.score.dto.UserScoreRecordDTO;
import com.agileboot.domain.performance.score.dto.UserScoreRecordImportResultDTO;
import com.agileboot.domain.performance.score.dto.UserScoreRecordImportTemplateDTO;
import com.agileboot.domain.performance.score.query.UserScoreRecordQuery;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.HashMap;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * 用户分数记录控制器
 */
@Tag(name = "用户分数记录API", description = "用户分数记录相关的增删查改")
@RestController
@RequestMapping("/performance/score")
@RequiredArgsConstructor
public class UserScoreRecordController {

    private final UserScoreRecordApplicationService userScoreRecordApplicationService;

    @Operation(summary = "获取用户分数记录列表")
    @GetMapping("/list")
    public ResponseDTO<PageDTO<UserScoreRecordDTO>> list(UserScoreRecordQuery query) {
        PageDTO<UserScoreRecordDTO> pageDTO = userScoreRecordApplicationService.getUserScoreRecordList(query);
        return ResponseDTO.ok(pageDTO);
    }

    @Operation(summary = "获取用户分数记录详情")
    @GetMapping("/{id}")
    public ResponseDTO<UserScoreRecordDTO> getInfo(@PathVariable Long id) {
        UserScoreRecordDTO dto = userScoreRecordApplicationService.getUserScoreRecordInfo(id);
        return ResponseDTO.ok(dto);
    }

    @Operation(summary = "新增用户分数记录")
    @PostMapping
    public ResponseDTO<Void> add(@RequestBody AddUserScoreRecordCommand addCommand) {
        userScoreRecordApplicationService.addUserScoreRecord(addCommand);
        return ResponseDTO.ok();
    }

    @Operation(summary = "修改用户分数记录")
    @PutMapping
    public ResponseDTO<Void> edit(@RequestBody UpdateUserScoreRecordCommand updateCommand) {
        userScoreRecordApplicationService.updateUserScoreRecord(updateCommand);
        return ResponseDTO.ok();
    }

    @Operation(summary = "删除用户分数记录")
    @DeleteMapping
    public ResponseDTO<Void> delete(@RequestBody List<Long> ids) {
        userScoreRecordApplicationService.deleteUserScoreRecord(ids);
        return ResponseDTO.ok();
    }

    /**
     * 导出所有用户分数记录
     * @param response HttpServletResponse
     * @param query 查询条件
     */
    @Operation(summary = "导出用户分数记录")
    @GetMapping("/excel")
    public void export(HttpServletResponse response, UserScoreRecordQuery query) {
        List<UserScoreRecordDTO> all = userScoreRecordApplicationService.getUserScoreRecordListAll(query);
        CustomExcelUtil.writeToResponse(all, UserScoreRecordDTO.class, response);
    }

    /**
     * 下载导入模板
     * @param response HttpServletResponse
     */
    @Operation(summary = "下载用户分数记录导入模板")
    @GetMapping("/excelTemplate")
    public void downloadTemplate(HttpServletResponse response) {
        List<UserScoreRecordImportTemplateDTO> templateData = userScoreRecordApplicationService.getImportTemplate();
        CustomExcelUtil.writeToResponse(templateData, UserScoreRecordImportTemplateDTO.class, response);
    }

    /**
     * 导入用户分数记录
     * @param file Excel文件
     * @return 导入结果
     */
    @Operation(summary = "导入用户分数记录")
    @PostMapping("/excel")
    public ResponseDTO<UserScoreRecordImportResultDTO> importExcel(@RequestParam("file") MultipartFile file) {
        // 读取Excel文件
        List<UserScoreRecordImportTemplateDTO> importDataList = 
                CustomExcelUtil.readFromRequest(UserScoreRecordImportTemplateDTO.class, file);
        
        // 执行批量导入
        UserScoreRecordImportResultDTO result = userScoreRecordApplicationService.batchImport(importDataList);
        
        return ResponseDTO.ok(result);
    }

    @Operation(summary = "提交用户分数统计任务")
    @PostMapping("/calculate/{userId}")
    public ResponseDTO<Void> calculate(@PathVariable Long userId) {
        userScoreRecordApplicationService.submitCalculateUserScoreTask(userId);
        return ResponseDTO.ok();
    }

    @Operation(summary = "批量提交所有用户的分数统计任务")
    @PostMapping("/calculate/all")
    public ResponseDTO<Void> calculateAll() {
        // 检查限流
        RateLimitInfoDTO rateLimitInfo = userScoreRecordApplicationService.checkBatchCalculateRateLimit();
        if (rateLimitInfo != null) {
            // 未到时间，返回错误信息和下次可调用时间
            ApiException exception = new ApiException(ErrorCode.Client.COMMON_REQUEST_TOO_OFTEN);
            HashMap<String, Object> payload = new HashMap<>();
            payload.put("nextAvailableTime", rateLimitInfo.getNextAvailableTime());
            payload.put("remainingSeconds", rateLimitInfo.getRemainingSeconds());
            exception.setPayload(payload);
            throw exception;
        }
        
        // 执行批量统计
        userScoreRecordApplicationService.submitCalculateAllUsersScoreTask();
        return ResponseDTO.ok();
    }
}

